标准控制流是一种可预测的推进过程:程序计数器根据顺序逻辑或显式跳转,从地址 $a_k$ 移动到 $a_{k+1}$。然而, 异常控制流(ECF) 代表了发生在这一正常流程之外的“突变”转移。
1. 数学模型
处理器执行是一个序列 $a_0, a_1, \dots, a_{n-1}$,其中每个 $a_k$ 对应一条指令 $I_k$。当处理器状态发生变化——一个 事件——触发跳转到一个应用程序当前代码路径中不存在的专用处理程序。
2. 实现层次
ECF 桥接了硬件与软件之间的鸿沟。它涵盖从硬件级 异常 (故障、中断)到操作系统级 上下文切换 以及 信号。
3. “突变”的现实
无论是用户按下 Ctrl+C 还是系统调用请求磁盘访问,异常控制流都会迫使 CPU 跳转到另一个“世界”——内核——确保系统对动态状态变化保持响应。
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
Practice Problem 8.1: Given Process A(1-3), B(2-5), and C(4-6), which pair is NOT concurrent?
Processes A and B
Processes A and C
Processes B and C
All processes are concurrent.
✅ Correct!
Processes A(1-3) and C(4-6) do not overlap in time; A finishes before C starts.❌ Incorrect
Concurrency requires a time overlap. A(1-3) and B(2-5) overlap at time 2. B(2-5) and C(4-6) overlap at time 4.QUESTION 2
Which function is called once but returns only if there is an error?
fork()
exit()
execve()
waitpid()
✅ Correct!
execve() overwrites the current process image; if successful, it never returns to the caller.❌ Incorrect
fork() returns twice. exit() never returns. waitpid() returns when a child changes state.QUESTION 3
In the mathematical model of control flow, what triggers an 'exceptional' transition?
A standard sequential instruction Iₖ₊₁
An explicit loop or function call
A change in processor state (Event)
The end of the program counter
✅ Correct!
ECF is defined by transitions triggered by events external or internal to the instruction stream, not normal logic.❌ Incorrect
Standard transitions (loops, calls) are part of normal control flow, not exceptional.QUESTION 4
Which function behavior matches: 'Called once, returns either a pointer or NULL'?
getenv()
fork()
exit()
longjmp()
✅ Correct!
getenv() searches for an environment variable and returns its pointer or NULL if not found.❌ Incorrect
fork() returns a PID/0. exit() returns nothing. longjmp() returns to setjmp().QUESTION 5
If a process receives a signal of type k while another signal of type k is pending, what happens?
The signal is queued.
The signal is discarded.
The kernel crashes.
The handler is interrupted by the new signal.
✅ Correct!
Signals are non-queuing; if a signal is already pending, subsequent instances of that same signal are dropped.❌ Incorrect
Signals of the same type do not queue in standard Unix systems.Case Study: Analyzing Execution Flow in global-waitprob1.c
Synchronization and ECF Transitions
Consider a program where a parent process calls fork() to create a child, and the parent immediately calls waitpid() to reap it. Analyze the resulting control flow divergence and convergence.
Q
How many output lines does this program generate and what is the ordering principle?
Solution:
The program generates 2 output lines. The ordering is strictly deterministic: the child's output must appear before the parent's final output because waitpid() acts as a synchronization barrier, forcing the parent's sequential flow to pause until the child's exceptional exit state is processed.
The program generates 2 output lines. The ordering is strictly deterministic: the child's output must appear before the parent's final output because waitpid() acts as a synchronization barrier, forcing the parent's sequential flow to pause until the child's exceptional exit state is processed.
Q
Required Output Task: Analyze the global-waitprob1.c execution flow (approx. 200 words).
Solution:
The execution of global-waitprob1.c serves as a textbook illustration of Exceptional Control Flow through process management. Upon reaching the fork() call at address a_k, the system state undergoes a profound transition. The operating system creates a duplicate logical control flow—the child—which begins its own sequence starting from a duplicate set of registers and address space. This creates a divergence where two distinct sequences (a_0...a_n) coexist. The parent process immediately encounters the waitpid() system call, which is a 'Trap' class exception. This call effectively places the parent's sequential instruction stream in a suspended state, waiting for a hardware-triggered event: the child's termination. In this moment, the child process executes its unique path independently. When the child calls exit(), an exceptional event occurs that notifies the kernel. The kernel then context-switches back to the parent, resolving the waitpid() block. This synchronization barrier ensures that the child's logical flow is 'reaped' before the parent proceeds. Ultimately, the two flows, though briefly concurrent and independent, are reconciled by the OS to ensure predictable output, proving that ECF is not chaotic but a highly structured collaboration between the hardware, kernel, and application logic.
The execution of global-waitprob1.c serves as a textbook illustration of Exceptional Control Flow through process management. Upon reaching the fork() call at address a_k, the system state undergoes a profound transition. The operating system creates a duplicate logical control flow—the child—which begins its own sequence starting from a duplicate set of registers and address space. This creates a divergence where two distinct sequences (a_0...a_n) coexist. The parent process immediately encounters the waitpid() system call, which is a 'Trap' class exception. This call effectively places the parent's sequential instruction stream in a suspended state, waiting for a hardware-triggered event: the child's termination. In this moment, the child process executes its unique path independently. When the child calls exit(), an exceptional event occurs that notifies the kernel. The kernel then context-switches back to the parent, resolving the waitpid() block. This synchronization barrier ensures that the child's logical flow is 'reaped' before the parent proceeds. Ultimately, the two flows, though briefly concurrent and independent, are reconciled by the OS to ensure predictable output, proving that ECF is not chaotic but a highly structured collaboration between the hardware, kernel, and application logic.